#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <fcntl.h>
#include <unistd.h>

#include <err.h>
#include <sysexits.h>

#define INITIAL_SIZE 64

int
main(int argc, char *argv[])
{
	uint8_t b[INITIAL_SIZE];
	const char *util = NULL;
	ssize_t r;
	int fd;

	if (argv[1] == NULL)
		goto usage;
	if ((fd = open(argv[1], O_RDONLY)) < 0)
		err(EX_NOINPUT, "%s", argv[1]);
	if ((r = read(fd, b, sizeof(b))) < 0)
		err(EX_IOERR, "%s", argv[1]);
	if (r < 4)
		err(EX_DATAERR, "%s", argv[1]);
	if (memcmp(b, ".snd", 4) == 0) {
		util = "au2au";
	} else if (memcmp(b, "FORM", 4) == 0) {
		if (r < 12)
			return (1);
		if (memcmp(b + 8, "AIFF", 4) != 0 &&
		    memcmp(b + 8, "AIFC", 4) != 0)
			util = "aiff2au";
	} else if (memcmp(b, "RIFF", 4) == 0) {
		if (r < 12)
			return (1);
		if (memcmp(b + 8, "WAVE", 4) == 0)
			util = "wav2au";
	} else if (memcmp(b, "fLaC", 4) == 0) {
		util = "flac2au";
	} else if (memcmp(b, "OggS", 4) == 0) {
		if (r < 36)
			return (1);
		if (memcmp(b + 28, "\x01vorbis", 7) == 0)
			util = "vorbis2au";
		else if (memcmp(b + 28, "\177FLAC", 5) == 0)
			util = "flac2au";
	} else if (memcmp(b, "ID3", 3) == 0) {
		util = "mpg2au";
	} else if (
	    b[0] == 0xFF && (b[1] & 0xE0) == 0xE0 &&	/* frame sync */
	    (b[1] & 0x18) != 0x08 &&			/* version */
	    (b[1] & 0x06) != 0x00 &&			/* layer */
	    (b[2] & 0xF0) != 0xF0 &&			/* bit-rate */
	    (b[2] & 0x0C) != 0x0C &&			/* frequency */
	    (b[3] & 0x03) != 0x02			/* emphasis */
	    ) {
		util = "mpg2au";
	}
	if (util == NULL)
		return (1);
	if (lseek(fd, 0, SEEK_SET) != 0)
		err(EX_USAGE, "%s", argv[1]);
	if (dup2(fd, STDIN_FILENO) != STDIN_FILENO)
		err(EX_OSERR, "dup2(2)");
	argv[1] = (char *)util;
	(void)execvp(util, argv + 1);
	return (1);
usage:
	(void)fprintf(stderr, "usage: auopen file [argument ...]\n");
	return (EX_USAGE);
}
